#ifndef _ASDU_TYPE_H_
#define _ASDU_TYPE_H_


/**
 * @brief  ASDU 类型标识符 
*/
enum asdutype { 
	M_SP_NA_1 =   1, ///<1> 单点信息  √
	M_SP_TA_1,///<2> 带时标的单点信息  √
	M_DP_NA_1,///<3> 双点信息   √
	M_DP_TA_1,///<4> 带时标的双点信息  √
	M_ST_NA_1,///<5> 步位置信息 √
	M_ST_TA_1,///<6> 带时标的步位置信息 √
	M_BO_NA_1,///<7> 32 比特串 √
	M_BO_TA_1,///<8> 带时标的 32 比特串 √
	M_ME_NA_1,///<9> 测量值 ，规一化值 √
	M_ME_TA_1,///<10> 带时标的测量值 ，规一化值 √
	M_ME_NB_1,///<11> 测量值 ，标度化值 √
	M_ME_TB_1,///<12> 带时标的测量值 ，标度化值 √
	M_ME_NC_1,///<13> 测量值 ，短浮点数 √
	M_ME_TC_1,///<14> 带时标的测量值 ，短浮点数 √
	M_IT_NA_1,///<15> 累计量  √
	M_IT_TA_1,///<16> 带时标的累计量 √
	M_EP_TA_1,///<17> 带时标的继电保护装置事件  √
	M_EP_TB_1,///<18> 带时标的继电保护装置成组启动事件  √
	M_EP_TC_1,///<19> 带时标的继电保护装置成组输出电路信息 √
	M_PS_NA_1,///<20> 带变位检出的成组单点信息 √
	M_ME_ND_1,///<21> 测量值 , 不带品质描述词的规一化值 √
	M_SP_TB_1  =  30 ,///<30> 带 CP56Time2a 时标的单点信息 √
	M_DP_TB_1,///<31> 带 CP56Time2a 时标的双点信息 √
	M_ST_TB_1,///<32> 带 CP56Time2a 时标的步位置信息 √
	M_BO_TB_1,///<33> 带 CP56Time2a 时标的 32 比特串 √
	M_ME_TD_1,///<34> 带 CP56Time2a 时标的测量值 ，规一化值 √
	M_ME_TE_1,///<35> 带 CP56Time2a 时标的测量值 ，标度化值 √
	M_ME_TF_1,///<36> 带 CP56Time2a 时标的测量值 ，短浮点数 √
	M_IT_TB_1,///<37> 带 CP56Time2a 时标的累计量  √
	M_EP_TD_1,///<38> 带 CP56Time2a 时标的继电保护装置事件  √
	M_EP_TE_1,///<39> 带 CP56Time2a 时标的继电保护装置成组启动事件  √
	M_EP_TF_1,///<40> 带 CP56Time2a 时标的继电保拌装置成组输出电路信息 √
	C_SC_NA_1  = 45,///<45> 单点命令 √
	C_DC_NA_1,///<46> 双点命令 √
	C_RC_NA_1,///<47> 调节步命令 √
	C_SE_NA_1,///<48> 设定值命令 ，规一化值 √
	C_SE_NB_1,///<49> 设定值命令 ，标度化值 √
	C_SE_NC_1,///<50> 设定值命令 ，短浮点数 √
	C_BO_NC_1,///<51> 32 比特串 √
	C_SC_TA_1   = 58 ,///<58> 带 CP56Time2a 时标的单点命令
	C_DC_TA_1,///<59> 带 CP56Time2a 时标的双点命令
	C_RC_TA_1,///<60> 带 CP56Time2a 时标的步调节
	C_SE_TA_1,///<61> 带 CP56Time2a 时标的设定值命令，归一化值
	C_SE_TB_1,///<62> 带 CP56Time2a 时标的设定值命令，标度化值
	C_SE_TC_1,///<63> 带 CP56Time2a 时标的设定值命令，短浮点数
	C_BO_TA_1,///<64> 带 CP56Time2a 时标的 32 比特串

	M_EI_NA_1   = 70, ///<70> 初始化结束 √
	C_IC_NA_1   = 100,///<100> 总召唤命令 √
	C_CI_NA_1,///<101> 累计量召唤命令  √
	C_RD_NA_1,///<102> 读命令 
	C_CS_NA_1,///<103> 时钟同步命令  √
	C_TS_NA_1,///<104> 测试命令 
	C_RP_NA_1,///<105> 复位进程命令 
	C_CD_NA_1,///<106> 收集传输延时
	C_TS_TA_1,///<107> 带 CP56Time2a 时标的测试命令
	P_ME_NA_1   = 110,///<110> 测量值参数 ，规一化值 
	P_ME_NB_1,///<111> 测量值参数，标度化值 
	P_ME_NC_1,///<112> 测量值参数 ，短浮点数 
	P_AC_NA_1,///<113> 参数激活 
	F_FR_NA_1   = 120,///<120> 文件淮备就绪 
	F_SR_NA_1,///<121> 节淮备就绪 
	F_SC_NA_1,///<122> 召唤目录，选择文件 ，召唤文件召唤节 
	F_LS_NA_1,///<123> 最后的节，最后的段 
	F_AF_NA_1,///<124> 认可文件，认可节 
	F_SG_NA_1,///<125> 段 
	F_DR_NA_1,///<126> 目录 
	          ///<136> 多对象设 定值命令（特殊 ASDU ）
};


/// ASDU 数据包下标索引。
typedef struct ASDUindex{
	unsigned char type     ; ///< ASDU 包类型  TYPE
	unsigned char qualifier; ///< ASDU 可变结构限定词 VSQ
	unsigned char cause    ; ///< 传输原因，1/2 字节，COT
	unsigned char cmnaddr  ; ///< 公共地址，1/2 字节 ADDR
	unsigned char info     ; ///< 信息体索引位置 INFO
}
ASDUindex_t ; ///< 根据 addrlen 和 causelen 的 ASDU 索引值，只读



typedef enum iecgrp {
	IEC_GRP_ALL = 0x14 , ///< 总召唤
	IEC_GROUP_1,      ///< 第 1 组召唤
	IEC_GROUP_2,      ///< 第 2 组召唤
	IEC_GROUP_3,      ///< 第 3 组召唤
	IEC_GROUP_4,      ///< 第 4 组召唤
	IEC_GROUP_5,      ///< 第 5 组召唤
	IEC_GROUP_6,      ///< 第 6 组召唤
	IEC_GROUP_7,      ///< 第 7 组召唤
	IEC_GROUP_8,      ///< 第 8 组召唤
	IEC_GROUP_9,      ///< 第 9 组召唤
	IEC_GROUP_10,     ///< 第 10 组召唤
	IEC_GROUP_11,     ///< 第 11 组召唤
	IEC_GROUP_12,     ///< 第 12 组召唤
	IEC_GROUP_13,     ///< 第 13 组召唤
	IEC_GROUP_14,     ///< 第 14 组召唤
	IEC_GROUP_15,     ///< 第 15 组召唤
	IEC_GROUP_16      ///< 第 16 组召唤
}
iecgrp_t;


/** 从机突发事件类型 */
typedef enum slv_event {
	EVENT_SIQ0T  = M_SP_NA_1  , ///< 不带时标的单点信息
	EVENT_SIQ24T = M_SP_TA_1  , ///< 带时标的单点信息,SOE
	EVENT_DIQ0T  = M_DP_NA_1  , ///< 不带时标的双点信息
	EVENT_DIQ24T = M_DP_TA_1  , ///< 带时标的双点信息
	EVENT_STD0T  = M_ME_NC_1  , ///< 测量值 ，短浮点数
	EVENT_STD24T = M_ME_TC_1  , ///< 带时标的测量值 ，短浮点数
}
slv_event_t;


/// 总线忙碌状态值
enum iec_busy {
	IEC10x_IDLE            = 0        ,
	IEC10x_HEARTBEAT       = (1 << 0) , ///< 正在链路测试
	IEC10x_SUMMON          = (1 << 1) , ///< 正在进行总召
	IEC10x_SYNC            = (1 << 2) , ///< 正在对时
	IEC10x_CTRLING         = (1 << 3) , ///< 正在执行遥控
	IEC10x_FILE            = (1 << 4) , ///< 正在传输文件
	IEC101_WAITING_CONFORM = (1 << 5) , ///< 101 等待确认帧
};


/**@name    bus->mode 模式字
  * @brief  mode 表示了当前总线的类型，是否为主站/平衡模式等
  * @{
*/
#define IEC_MASTER     (1 << 0)
#define IEC_101        (1 << 1)
#define IEC_BALANCE    (1 << 2)
#define IEC_PARSER     (1 << 3)
#define IEC_DIRECT     (1 << 7)
/** @}*/


#define IEC_DISCONNECTED 0
#define IEC_CONNECTED    1

#define IEC_TYPE         0
#define IEC_QUALIFIER    1
#define IEC_COT          2

/**
  * @brief 根据传输原因长度和公共地址长度生成 
  *        COMMON_ADDR,INFO 用于索引 ASDU 信息
*/
#define IEC_INDEX(cotlen,cmnaddrlen) \
	const int IEC_COMMON_ADDR=IEC_COT+(cotlen),IEC_INFO=IEC_COMMON_ADDR+(cmnaddrlen)


/**
  * @brief 根据类型返回 ASDU 发送缓冲区地址
*/
#define ASDU_TXBUFF(b) \
((b)->mode & IEC_101) ? &(b)->txbuf[5+(b)->iec101.lnaddrlen] : &(b)->txbuf[6]

#endif
